#include "uartPort.h"
#include "cmsis_os2.h"
#include "dataProcess.h"
#include "my_uart.h"
#include "SEGGER_RTT.h"
#include "dataPool.h"
// #include "printf.h"

USART_Data uart1_data;
USART_Data uart2_data;
//每个端口有a,b两个数据区交替使用
DataFrame frame[PORT_NUM][2];//每个端口两个数据区
void uartCallback(USART_Data *me){
    uint16_t len = USART_DataGetReceivedLen(me);
    uint8_t* data = USART_GetData(me);
    uint8_t bufferUsed = 0;//0:a 1:b
    DataFrame* framePtr = NULL;
    uint8_t port;
    //找到是哪个端口
    if(me->huart==&huart1){
        port = 1;
    }
    else if(me->huart==&huart2){
        port = 2;
    }
    else{
        return;//错误
    }
    //找到是哪个数据区
    if(data == frame[port-1][0].p){
        bufferUsed = 0;
        framePtr = &frame[port-1][0];
    }
    else if(data == frame[port-1][1].p){
        bufferUsed = 1;
        framePtr = &frame[port-1][1];
    }
    else{
        return;//错误
    }
    uint8_t status = USART_DataIsReceived(me)?0:1;
    uint8_t store=0;//存储标志，0:需要存储 1:缓冲区不足，丢弃这个包

    //重新开启接收，先接收，避免丢数据
    DataFrame* frameOldPtr = framePtr;
    if (len != 0 || status != 0){//如果不是空包，就要换数据区
        if(frame[port-1][(bufferUsed+1)%2].p != NULL){//有可用数据区
            framePtr = &frame[port-1][(bufferUsed+1)%2];
        }
        else{
            store = 1;//没有可用数据区，丢弃这个包
            framePtr = &frame[port-1][bufferUsed];//继续使用当前数据区
        }
    }
    //在新的数据区中开启接收
    me->usart_rx_buf = framePtr->p;
    me->rxSize_Max = framePtr->total_len;
    if(status == 0){
        USART_DataResetReceivedFlag(me);//清除接收完成标志位
        HAL_UARTEx_ReceiveToIdle_DMA(me->huart, me->usart_rx_buf, me->rxSize_Max);
        __HAL_DMA_DISABLE_IT(me->huart->hdmarx , DMA_IT_HT);  // 关闭半传输中断,防止半传输中断影响接收完成标志位和接收长度
    }
    else{
        my_UART_Receive_DMA(me->huart, me->usart_rx_buf, me->rxSize_Max);
        __HAL_DMA_DISABLE_IT(me->huart->hdmarx , DMA_IT_HT);  // 关闭半传输中断,防止半传输中断影响接收完成标志位和接收长度
    }

    //处理数据
    if(store == 1){
        SEGGER_RTT_WriteString(0, "one pack is discarded\r\n");
    }
    else if (len > 0) {
      data_finish(frameOldPtr,len,status);
      
      SEGGER_RTT_printf(0,"[%lu]data_finish,len=%u,status = %u\r\n",osKernelGetTickCount(),len,status);
      SEGGER_RTT_printf(0,"port:%d\r\n",frameOldPtr->port);
    } else if (len == 0 && status == 0) {  // len == 0
      data_appendFinishFlag(port);
      SEGGER_RTT_WriteString(0,"appendFinishFlag\r\n");
    }

    //获得新的数据区
    if (len != 0 || status != 0){//如果不是空包，就要获得新的数据区
        uint8_t ret ;
        if(store == 0){//如果没有丢包，就获得新的数据区
            ret = getDataArea(frameOldPtr,port);
        }
        else{
            ret = getDataArea(&frame[port-1][(bufferUsed+1)%2],port);
        }
        if (ret != 0) {
            // 错误处理
            SEGGER_RTT_WriteString(0, "no dataPool to used");
        }
    }
}

void uartPort_init(){
    getDataArea(&frame[0][0],1);
    getDataArea(&frame[1][0],2);
    getDataArea(&frame[0][1],1);
    getDataArea(&frame[1][1],2);
    if(frame[0][0].p != NULL){
        USART_DataTypeInit(&uart1_data, &huart1, frame[0][0].p, frame[0][0].total_len, DMA_CIRCULAR_MODE, uartCallback);
    }
    else{
        // 内存分配失败
    }
    if(frame[1][0].p != NULL){
        USART_DataTypeInit(&uart2_data, &huart2, frame[1][0].p, frame[1][0].total_len, DMA_CIRCULAR_MODE, uartCallback);
    }
    else{
        // 内存分配失败
    }
    if(frame[0][1].p == NULL || frame[1][1].p == NULL){
        // 内存分配失败
    }


}

void uartPort_stop(){
    HAL_UART_AbortReceive_IT(&huart1);
    HAL_UART_AbortReceive_IT(&huart2);
    while(osMessageQueueGetCount(dataSaveQueue)>0){//等待存储队列清空
        osDelay(10);
    }
    osDelay(10);
    // while(osThreadGetState(dataSaveTask) != osThreadBlocked){//等待存储任务结束
    //     osDelay(10);
    // }
    //释放两个正在使用的数据区
    typedef struct{
    uint8_t(* pool)[DATA_POOL_SIZE];
    uint8_t num;
    uint16_t size;
    osMessageQueueId_t queue;
}DataPoolHeadle;
extern DataPoolHeadle dataPoolHeadle;
    SEGGER_RTT_printf(0,"dataPool num before free:%lu\r\n",osMessageQueueGetCount(dataPoolHeadle.queue));
    data_destroy(&frame[0][0]);
    data_destroy(&frame[1][0]);
    data_destroy(&frame[0][1]);
    data_destroy(&frame[1][1]);
    SEGGER_RTT_printf(0,"dataPool num after free:%lu\r\n",osMessageQueueGetCount(dataPoolHeadle.queue));
}
void uartPort_start(){
    getDataArea(&frame[0][0],1);
    getDataArea(&frame[1][0],2);
    getDataArea(&frame[0][1],1);
    getDataArea(&frame[1][1],2);
    USART_DataResetReceivedFlag(&uart1_data);//清除接收完成标志位
    uart1_data.usart_rx_buf = frame[0][0].p;
    uart1_data.rxSize_Max = frame[0][0].total_len;
    HAL_UARTEx_ReceiveToIdle_DMA(&huart1, frame[0][0].p, frame[0][0].total_len);
    __HAL_DMA_DISABLE_IT(huart1.hdmarx , DMA_IT_HT);  // 关闭半传输中断,防止半传输中断影响接收完成标志位和接收长度
    USART_DataResetReceivedFlag(&uart2_data);//清除接收完成标志位
    uart2_data.usart_rx_buf = frame[1][0].p;
    uart2_data.rxSize_Max = frame[1][0].total_len;
    HAL_UARTEx_ReceiveToIdle_DMA(&huart2, frame[1][0].p, frame[1][0].total_len);
    __HAL_DMA_DISABLE_IT(huart2.hdmarx , DMA_IT_HT);  // 关闭半传输中断,防止半传输中断影响接收完成标志位和接收长度

}
    